﻿/* 
 * Copyright 2010 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Ngilead.Core.Utils
{
    /// <summary>
    /// Implementation of the ThreadLocal container.
    /// </summary>
    /// <typeparam name="T">Type of the contained data</typeparam>
    public class ThreadLocal<T>
    {
        /*----------------------------------------------------------------------------------------*/
        #region Private variables

        /// <summary>
        /// The container dictionary : key is the hash code of the thrad, value is the stored data
        /// </summary>
        private Dictionary<int, T> container;

        #endregion
        /*----------------------------------------------------------------------------------------*/

        /*----------------------------------------------------------------------------------------*/
        #region Ctor
        /// <summary>
        /// Constructor
        /// </summary>
        public ThreadLocal()
        {
            container = new Dictionary<int, T>();
        }

        #endregion
        /*----------------------------------------------------------------------------------------*/

        /*----------------------------------------------------------------------------------------*/
        #region Public variables
        /// <summary>
        /// Get the thread stored data
        /// </summary>
        /// <returns></returns>
        public T Get()
        {
            int hash = Thread.CurrentThread.GetHashCode();
            if (container.Keys.Contains(hash))
            {
                return container[hash];
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// Store the data in the thread
        /// </summary>
        /// <param name="item"></param>
        public void Set(T item)
        {
            lock (container)
            {
                int hash = Thread.CurrentThread.GetHashCode();
                if (container.Keys.Contains(hash))
                {
                    container[hash] = item;
                }
                else
                {
                    container.Add(hash, item);
                }
            }
        }

        /// <summary>
        /// Clear the thread loal storage.
        /// Warning : clear data for all threads !
        /// </summary>
        public void Clear()
        {
            lock (container)
            {
                container.Clear();
            }
        }

        #endregion
        /*----------------------------------------------------------------------------------------*/
    }
}
